package protos

import (
	"encoding/base64"
	"encoding/json"
	"errors"

	"github.com/golang/protobuf/proto"
)

const (
	//EsDocIDSeparator ES中文档ID分隔符
	EsDocIDSeparator = "."

	//EsIndexBlock ES索引：区块
	EsIndexBlock = "hschain.block"

	//EsIndexExecBlock ES索引：已执行的区块
	EsIndexExecBlock = "hschain.executed-block"

	//EsIndexBlockExecResult ES索引：已执行的区块结果
	EsIndexBlockExecResult = "hschain.block-exec-result"

	//EsIndexPendingBlock ES索引：待验证的区块
	EsIndexPendingBlock = "hschain.pending-block"

	//EsIndexTx ES索引：交易
	EsIndexTx = "hschain.tx"

	//EsIndexExecTx ES索引：已执行的交易
	EsIndexExecTx = "hschain.executed-tx"

	//EsIndexPendingTx ES索引：待验证的交易
	EsIndexPendingTx = "hschain.pending-tx"

	//EsIndexStateDB ES索引：状态库
	EsIndexStateDB = "hschain.statedb"

	//EsIndexAccount ES索引：账户
	EsIndexAccount = "hschain.account"

	//EsIndexBalanceFreezeUnfreezeRecord ES索引：余额冻结解冻记录
	EsIndexBalanceFreezeUnfreezeRecord = "hschain.balance-freeze-unfreeze-record"

	//EsIndexSeqCenterBlock ES索引：区块（序列号中心存的区块索引）
	EsIndexSeqCenterBlock = "hschain.seqcenter.block"

	//EsIndexContract ES索引：合约
	EsIndexContract = "hschain.contract"

	//EsIndexContractEvent ES索引：合约事件
	EsIndexContractEvent = "hschain.contract.event"

	//EsIndexContractStatus ES索引：合约状态
	EsIndexContractStatus = "hschain.contract.status"

	//EsIndexContractVersion ES索引：合约版本
	EsIndexContractVersion = "hschain.contract.version"

	//EsIndexParaChain ES索引：平行链信息
	EsIndexParaChain = "hschain.parachain"

	//EsIndexParaChainValidatorSet ES索引：平行链验证人集合
	EsIndexParaChainValidatorSet = "hschain.parachain.validator-set"

	//EsIndexParaChainValidatorSetChangeRecord ES索引：平行链验证人集合变更记录
	EsIndexParaChainValidatorSetChangeRecord = "hschain.parachain.validator-set-change-record"

	//EsIndexParaChainTxPackage ES索引：平行链交易包
	EsIndexParaChainTxPackage = "hschain.parachain.tx-pkg"

	// EsDocFieldPayload ES文档字段payload，类型是binary
	EsDocFieldPayload = "_payload"
)

// UnmarshalEnhancedProtoMessage 将询返回的Source字段值转换成ProtobufDocument对象。
func UnmarshalEnhancedProtoMessage(source []byte, result interface{}) error {
	if len(source) == 0 {
		return errors.New("empty source")
	}
	pd, ok := result.(EnhancedProtoMessage)
	if !ok {
		return errors.New("doc must implements EnhancedProtoMessage ")
	}

	var mapDoc map[string]interface{}
	if err := json.Unmarshal(source, &mapDoc); err != nil {
		return err
	}
	if payloadObj, ok := mapDoc[EsDocFieldPayload]; ok {
		if payloadString, ok := payloadObj.(string); ok {
			dst, err := base64.StdEncoding.DecodeString(payloadString)
			if err != nil {
				return err
			}
			return proto.Unmarshal(dst, pd)
		}
	}
	return nil
}
